package com.szgd.controller;
import java.io.*;
import java.net.URLDecoder;
import java.text.SimpleDateFormat;
import java.util.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.szgd.util.*;
import org.activiti.engine.impl.util.json.JSONArray;
import org.activiti.engine.impl.util.json.JSONObject;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.CellStyle;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.User;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.szgd.bean.SysDict;
import com.szgd.paging.PageList;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;

public class BaseController {
    private static Logger logger = Logger.getLogger(BaseController.class);
    public final static String SUCCESS_CODE = "1";
    public final static String SUCCESS_MSG = "成功";
    public final static String ERROR_CODE = "0";
    public Map<String,Object> getSuccMap(String msg){
        Map<String,Object> map = new HashMap<String,Object>();
        map.put("resultCode", SUCCESS_CODE);
        map.put("resultMsg", msg);
        return map;
    }
    public Map<String,Object> getSuccMap(Object data){
        Map<String,Object> map = new HashMap<String,Object>();
        map.put("resultCode", SUCCESS_CODE);
        map.put("resultMsg", SUCCESS_MSG);
        map.put("data", data);

        return map;
    }
    public Map<String,Object> getErrorMap(String msg){
        Map<String,Object> map = new HashMap<String,Object>();
        map.put("resultCode", ERROR_CODE);
        map.put("resultMsg", msg);
        return map;
    }


    public ModelAndView getModelAndView(HttpServletRequest request, HttpSession httpSession,String viewName) {
        ModelAndView mv = new ModelAndView(viewName);
        Map<String, Object> map = new HashMap<String, Object>();
        Map<String, String[]> requestMap = request.getParameterMap();
        for (String key : requestMap.keySet()) {
            mv.addObject(key, StringUtil.arrayToStr((String[]) requestMap.get(key)));
        }
        return mv;
    }

    public void download(HttpServletResponse response, byte[] fileByte,String fileName) throws IOException {
        if(fileByte != null) {
            ByteArrayInputStream fis = new ByteArrayInputStream(fileByte);
            byte[] buffer;
            buffer = new byte[fis.available()];
            fis.read(buffer);
            fis.close();
            response.reset();
            // 设置response的Header
            //fileName = URLEncoder.encode(fileName,"UTF-8");
            fileName = new String(fileName.getBytes(), "ISO8859-1");
            response.addHeader("Content-Disposition", "attachment;filename=" + fileName);
            response.setContentType("application/octet-stream");    //自动匹配文件类型
            OutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
            outputStream.write(buffer);
            outputStream.flush();
            outputStream.close();
        }
    }


    /**
     * 生成申请编号 yyyyMMddhhmmss
     * @return
     */
    protected String generateApplyNo(String type){
        String no = TimeUtil.formatDate(Calendar.getInstance().getTime(), "yyyyMMddhhmmss");
        if (type != null)
            no = type + no;
        return no;
    }

    /**
     * 以流的形式下载文件
     *
     * @param response
     * @param fileAbsolutePath 待下载的文件全路径名
     */
    public void download(HttpServletResponse response, String fileAbsolutePath) throws IOException {
        File file = new File(fileAbsolutePath);
        InputStream fis = new BufferedInputStream(new FileInputStream(file));
        byte[] buffer;
        buffer = new byte[fis.available()];
        fis.read(buffer);
        fis.close();
        response.reset();
        // 设置response的Header
        String fileName = file.getName();
        //fileName = URLEncoder.encode(fileName,"UTF-8");
        fileName = new String(fileName.getBytes(),"ISO8859-1");
        long fileLength = file.length();
        response.addHeader("Content-Disposition", "attachment;filename="+ fileName);
        response.addHeader("Content-Length", "" + String.valueOf(fileLength));
        response.setContentType("application/octet-stream");    //自动匹配文件类型
        OutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
        outputStream.write(buffer);
        outputStream.flush();
        outputStream.close();
    }

    /*
    根据模板导出excel
     */
    public  boolean exportExcelByTemplate(Map<String, String> titleMap,List<Map<String, Object>> dataList,String filePath,String templateName) throws IllegalArgumentException, IllegalAccessException {
        String classpathString = this.getClass().getClassLoader().getResource("/").toString();
        classpathString = StringUtils.replace(classpathString, "file:", "");
        InputStream is = null;
        OutputStream output = null;
        try {
            output = new FileOutputStream(new File(filePath));
            String templatePath = URLDecoder.decode(classpathString + "/template/"+templateName , "gb2312");
            is = new FileInputStream(new File(templatePath));
            HSSFWorkbook wb = new HSSFWorkbook(is);
            HSSFSheet sheet = wb.getSheetAt(0);

            CellStyle cellStyle = sheet.getRow(1).getCell(1).getCellStyle();
            int rowPoint = 1;
            Set<String> titleKeySet = titleMap.keySet();
            for ( Map<String, Object> data : dataList){
                HSSFRow row  = sheet.createRow(rowPoint);
                int cellPoint = 0;
                for(String key : titleKeySet){
                    HSSFCell cell = row.createCell(cellPoint);
                    String strVal = "";
//                    if(cellPoint == 0){
//                        strVal = String.valueOf(rowPoint);
//                    }else {
                        strVal = data.get(key) == null ? "" : String.valueOf(data.get(key));
//                    }
                    cell.setCellValue(strVal);
                    cell.setCellStyle(cellStyle);
                    cellPoint ++;
                }
                HSSFCell cell = row.createCell(cellPoint);
                String strVal = data.get("ERROR_MSG") == null ? "" : String.valueOf(data.get("ERROR_MSG"));
                cell.setCellValue(strVal);
                cell.setCellStyle(cellStyle);

                rowPoint ++;
            }

            wb.write(output);
            output.flush();
            output.close();
            return true;
        } catch (IOException e) {
            return false;
        }
    }

    /*
    导出excel-多个sheet
     */
    public  boolean exportExcel(Map<String, String> titleMap,Map<String, String> titleMap2,List<Map<String, Object>> dataList,List<Map<String, Object>> dataList2,String filePath,String templateName) throws IllegalArgumentException, IllegalAccessException {
        String classpathString = this.getClass().getClassLoader().getResource("/").toString();
        classpathString = StringUtils.replace(classpathString, "file:", "");
        InputStream is = null;
        OutputStream output = null;
        try {
            output = new FileOutputStream(new File(filePath));
            String templatePath = URLDecoder.decode(classpathString + "/template/"+templateName , "gb2312");
            is = new FileInputStream(new File(templatePath));
            HSSFWorkbook wb = new HSSFWorkbook(is);
            //获取第一个sheet
            HSSFSheet sheet = wb.getSheetAt(0);

            CellStyle cellStyle = sheet.getRow(1).getCell(1).getCellStyle();
            int rowPoint = 1;
            Set<String> titleKeySet = titleMap.keySet();
            for ( Map<String, Object> data : dataList){
                HSSFRow row  = sheet.createRow(rowPoint);
                int cellPoint = 0;
                for(String key : titleKeySet){
                    HSSFCell cell = row.createCell(cellPoint);
                    String strVal = "";
                    strVal = data.get(key) == null ? "" : String.valueOf(data.get(key));
                    cell.setCellValue(strVal);
                    cell.setCellStyle(cellStyle);
                    cellPoint ++;
                }
                HSSFCell cell = row.createCell(cellPoint);
                String strVal = data.get("ERROR_MSG") == null ? "" : String.valueOf(data.get("ERROR_MSG"));
                cell.setCellValue(strVal);
                cell.setCellStyle(cellStyle);

                rowPoint ++;
            }

            //获取第2个sheet
            HSSFSheet sheet2 = wb.getSheetAt(1);

            CellStyle cellStyle2 = sheet2.getRow(1).getCell(1).getCellStyle();
            int rowPoint2 = 1;
            Set<String> titleKeySet2 = titleMap2.keySet();
            for ( Map<String, Object> data2 : dataList2){
                HSSFRow row2  = sheet2.createRow(rowPoint2);
                int cellPoint = 0;
                for(String key : titleKeySet2){
                    HSSFCell cell = row2.createCell(cellPoint);
                    String strVal = "";
                    strVal = data2.get(key) == null ? "" : String.valueOf(data2.get(key));
                    cell.setCellValue(strVal);
                    cell.setCellStyle(cellStyle2);
                    cellPoint ++;
                }
                HSSFCell cell = row2.createCell(cellPoint);
                String strVal = data2.get("ERROR_MSG") == null ? "" : String.valueOf(data2.get("ERROR_MSG"));
                cell.setCellValue(strVal);
                cell.setCellStyle(cellStyle2);

                rowPoint2 ++;
            }

            wb.write(output);
            output.flush();
            output.close();
            return true;
        } catch (IOException e) {
            return false;
        }
    }

    /**
     * 获得参数
     *
     * @param param
     * @return
     */
    protected String getParam(HttpServletRequest request , String param) {
        String value = request.getParameter(param.trim());
        return ("".equals(value) || value == null) ? "" : value;
    }

    /**
     * 将对象以json数据格式进行响应输出
     * @param response HttpServletResponse
     * @param obj 对象（List/Map均可）
     */
    protected void outJSONData(HttpServletResponse response, Object obj) {
        try {
            response.setContentType("text/javascript;charset=UTF-8");
            PrintWriter out = response.getWriter();
            out.print(obj);
            out.flush();
            out.close();
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
    }

    /**
     * 创建JSONObject对象
     * @return JSONObject
     */
    protected JSONObject getJson() {
        return new JSONObject();
    }

    /**
     * 获得request中所有的参数
     * @param request HttpServletRequest
     * @return 以Map<String, Object>的格式返回
     */
    protected Map<String, Object> getMapParams(HttpServletRequest request) {
        Map<String, Object> map = new HashMap<String, Object>();
        Map<String, String[]> requestMap = request.getParameterMap();
        for (String key : requestMap.keySet()) {
            map.put(key, StringUtil.arrayToStr((String[]) requestMap.get(key)));
        }
        return map;
    }

    /**
     * 打印输出datatable需要的数据结构
     * @param response HttpServletResponse
     * @param list List<Map<String, String>>  结果集
     */
    protected void outTableJSONData(HttpServletResponse response,List<Map<String, String>> list) {
        try {
            response.setContentType("text/javascript;charset=UTF-8");
            PrintWriter out = response.getWriter();
            JSONObject json = getJson();
            System.out.println("class: "+ list.getClass());
            if (list instanceof PageList) {
                PageList pageList = (PageList) list;
                json.put("aaData", new JSONArray(pageList));
                json.put("iTotalRecords", pageList.getPaginator().getTotalCount());
                json.put("iTotalDisplayRecords", pageList.getPaginator().getTotalCount());
            } else {
                json.put("aaData", new JSONArray(list));
                json.put("iTotalRecords", list.size());
                json.put("iTotalDisplayRecords", list.size());
            }

            out.print(json);
            out.flush();
            out.close();
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
    }

    protected void outTableJSONDataAddMsg(HttpServletResponse response,List<Map<String, String>> list,String msg) {
        try {
            response.setContentType("text/javascript;charset=UTF-8");
            PrintWriter out = response.getWriter();
            JSONObject json = getJson();
            System.out.println("class: "+ list.getClass());
            if (list instanceof PageList) {
                PageList pageList = (PageList) list;
                json.put("aaData", new JSONArray(pageList));
                json.put("iTotalRecords", pageList.getPaginator().getTotalCount());
                json.put("iTotalDisplayRecords", pageList.getPaginator().getTotalCount());
                json.put("msg", msg);
            } else {
                json.put("aaData", new JSONArray(list));
                json.put("iTotalRecords", list.size());
                json.put("iTotalDisplayRecords", list.size());
                json.put("msg", msg);
            }

            out.print(json);
            out.flush();
            out.close();
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
    }

    protected <T> void outTableJSONDataAddBeanMsg(HttpServletResponse response,List<T> list,String msg) {
        try {
            response.setContentType("text/javascript;charset=UTF-8");
            PrintWriter out = response.getWriter();
            JSONObject json = fromListToJson(list);
            System.out.println("class: "+ list.getClass());
            if (list instanceof PageList) {
                PageList pageList = (PageList) list;
                json.put("aaData", new JSONArray(pageList));
                json.put("iTotalRecords", pageList.getPaginator().getTotalCount());
                json.put("iTotalDisplayRecords", pageList.getPaginator().getTotalCount());
                json.put("msg", msg);
            } else {
                json.put("aaData", new JSONArray(list));
                json.put("iTotalRecords", list.size());
                json.put("iTotalDisplayRecords", list.size());
                json.put("msg", msg);
            }

            out.print(json);
            out.flush();
            out.close();
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
    }

    protected <T> void outTableJSONDataCommon(HttpServletResponse response, List<T> list) {
        try {
            response.setContentType("text/javascript;charset=UTF-8");
            PrintWriter out = response.getWriter();
            JSONObject json = fromListToJson(list);
            out.print(json);
            out.flush();
            out.close();
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
    }

    protected <T> JSONObject  fromListToJson(List<T> lists) {
        JSONObject json = getJson();
        if (lists instanceof PageList) {
            PageList<T> pageList = (PageList<T>) lists;
            json.put("aaData", new JSONArray(pageList));
            json.put("iTotalRecords", pageList.getPaginator().getTotalCount());
            json.put("iTotalDisplayRecords", pageList.getPaginator().getTotalCount());
        } else {
            json.put("aaData", new JSONArray(lists));
            json.put("iTotalRecords", lists.size());
            json.put("iTotalDisplayRecords", lists.size());
        }
        return json;
    }

    protected <T> T fromJsonToModel(String jsonString, Class<T> clazz) {

        T object = null;
        if(jsonString != null){
            try {
                ObjectMapper objectMapper = new ObjectMapper();
                object =   objectMapper.readValue(jsonString, clazz);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return object;
    }

    /**
     * 经费模块项目进度管理过滤
     * @param processPhaseListInDict
     * @param projectProcessList
     */
    List<Map<String,String>> getFilterPhaseSteps(List<SysDict> processPhaseListInDict, List<Map<String, String>> projectProcessList) {
        //3. 过滤
        List<Map<String, String>> phaseSteps = new LinkedList<>();

        int seq = 1;
        for (SysDict dictPhase: processPhaseListInDict){
            String phasePosition = "";
            if(seq == 1){
                phasePosition = "first";
            }else if(seq == processPhaseListInDict.size()){
                phasePosition = "last";
            }
            String dictId = dictPhase.getId();
            String phaseDate = "";
            String phaseStatus = "FUTURE";
            for (Map<String, String> projectPhase : projectProcessList){
                String phaseKey = projectPhase.get("PROCESS_PHASE");
                if(dictId.equals(phaseKey)){
                    phaseDate = projectPhase.get("PHASE_DATE");
                    String isCurrentNode = projectPhase.get("IS_CURRENT_NODE");
                    if(isCurrentNode.equals("1")) {
                        phaseStatus = "NOW";
                    }else{
                        phaseStatus = "LAST";
                    }
                }
            }
            Map<String, String> phaseStep = new HashMap<>();
            phaseStep.put("PHASE_ID",dictPhase.getId());
            phaseStep.put("PHASE_POSITION",phasePosition);
            phaseStep.put("PHASE_NAME",dictPhase.getDictValue());
            phaseStep.put("PHASE_SORT",String.valueOf(dictPhase.getDictSort()));
            phaseStep.put("PHASE_DATE",phaseDate);
            phaseStep.put("PHASE_STATUS",phaseStatus);   //过去LAST,当前NOW,将来FUTURE
            phaseSteps.add(phaseStep);
            seq++;
        }

        return phaseSteps;

    }


    /**
     * 获得SESSION里的用户信息
     *@param session HttpSession
     * @return Map<String, Object> 用户对象信息
     */
    protected Map<String, Object> getUserMap(HttpSession session) {
        return (Map<String, Object>) session.getAttribute("userInfo");
    }

    /**
     * 获得SESSION里的用户部门信息
     *@param session HttpSession
     * @return Map<String, Object> 用户部门信息 {DEPT_CD:'部门代码',DEPT_NAME:'部门名称'}
     */
    protected Map<String, Object> getUserDeptMap(HttpSession session) {
        return (Map<String, Object>) session.getAttribute("userDeptMap");
    }

    /**
     * 从session中获得用户id
     * @param session HttpSession
     * @return 用户id
     */
    protected Integer getUserId(HttpSession session) {
        return (Integer) getUserMap(session).get("userId");
    }

    /**
     * 从session中获得用户名称
     * @param session HttpSession
     * @return userName
     */
    protected String getUserName(HttpSession session) {
        return (String) getUserMap(session).get("userCnName");
    }

    protected String getLoginId(HttpSession session) {
        return (String) getUserMap(session).get("loginId");
    }

    protected Integer getPersonnelId(HttpSession session) {
        return (Integer) getUserMap(session).get("personnelId");
    }

    /**
     * 从session中获得用户id
     * @param session HttpSession
     * @return 用户id
     */
    protected String getDeptCd(HttpSession session) {
        User user= UserUtil.getUserInfomationBeanFromSession(session);
        String deptcd = user.getDeptCd();
        return deptcd;
    }

    /**
     * 从session中获得用户id
     * @param session HttpSession
     * @return 用户id
     */
    protected int getDeptParentId(HttpSession session) {
        User user= UserUtil.getUserInfomationBeanFromSession(session);
        int deptParentId = user.getDeptParentId();
        return deptParentId;
    }

}
